package com.giveu.signature.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.giveu.common.bean.result.Result;
import com.giveu.common.exception.ResultRuntimeException;
import com.giveu.common.service.RedisService;
import com.giveu.common.utils.DateUtil;
import com.giveu.common.utils.HttpKit;
import com.giveu.common.utils.HttpUtil;
import com.giveu.signature.bean.TemplateHtmlParam;
import com.giveu.signature.bean.TemplateHtmlParam.TemplateParam;
import com.giveu.signature.bean.TemplatePdf;
import com.giveu.signature.common.service.GenModelService;
import com.giveu.signature.common.util.FreeMarkUtil;
import com.giveu.signature.conts.RedisKey;
import com.giveu.signature.service.PdfGenerateService;

import io.swagger.annotations.Api;
@Api(tags = "PDF文件服务接口")
@RestController
@Service
public class PdfGenerateServiceImpl implements PdfGenerateService {

	private static final Logger log = LoggerFactory.getLogger(PdfGenerateServiceImpl.class);
	
	@Autowired
	RedisService redisService;

	@SuppressWarnings("null")
	@Override
	public Result<String> genPdf(@RequestBody @Valid TemplatePdf req) {
		if(req.getTempVerson()==null){
			Map<String, String> maxMap = redisService.getMapByString(RedisKey.SIGN_TEMPLATE_MAX_VERSION_MAP);
			if(maxMap==null||!maxMap.containsKey(req.getTempCode())){
				throw new ResultRuntimeException("模板不存在");
			}
			req.setTempVerson(Integer.parseInt(maxMap.get(req.getTempCode())));
		}
		Map<String, String> tMap = redisService.getMapByString(RedisKey.SIGN_TEMPLATE_MAP);
		String key = req.getTempCode()+":v"+req.getTempVerson();
		if(tMap==null||!tMap.containsKey(key)||StringUtils.isBlank(tMap.get(key))){
			throw new ResultRuntimeException("模板不存在");
		}
		TemplateHtmlParam tp = JSON.parseObject(tMap.get(key),TemplateHtmlParam.class);
		if(tp==null){
			throw new ResultRuntimeException("模板解析异常,"+tMap.get(key));
		}
		HttpServletResponse response = HttpKit.getResponse();
		OutputStream out = null;
		try {
			setDownloadHeader(response,UUID.randomUUID()+".pdf");
			out = response.getOutputStream();
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("signDate", DateUtil.getNowDate());
			if(tp.getTemplateParams()!=null&&!tp.getTemplateParams().isEmpty()){
				for (TemplateParam param : tp.getTemplateParams()) {
					String paramData = FreeMarkUtil.renderStr(param.getHttpParam(), req.getParamMap().get(param.getParamCode()));
					String res = HttpUtil.postJsonApi(param.getHttpUrl(), paramData);
					if(StringUtils.isBlank(res)){
						throw new ResultRuntimeException("请求返回为空,"+JSON.toJSONString(param));
					}
					JSONObject ob = JSON.parseObject(res);
					if(!ob.containsKey("status")||!ob.getBoolean("status")){
						throw new ResultRuntimeException("请求异常,"+JSON.toJSONString(param)+"("+ob.getString("message")+")");
					}
					map.put(param.getParamCode(), ob.get("data"));
				}
			}
			GenModelService.getModel(tp.getGenModel()).genPdfOutputStream(out, tp, map);
			out.flush();
		} catch (ResultRuntimeException ex) {
			log.error("文件生成异常：",ex);
			throw ex;
		}catch (Exception ex) {
			log.error("文件生成异常：",ex);
			throw new ResultRuntimeException(ex.getMessage());
		}finally {
			try {
				out.close();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		return null;
	}

	private void setDownloadHeader(HttpServletResponse response, String fileName2) throws IOException {
		String filename = new String(fileName2.getBytes("UTF-8"), "ISO8859-1");//控制文件名编码
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Disposition", "attachment;fileName=" + filename);// 设置文件名
	}

}
